package com.googlecode.maratische.google.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import com.googlecode.maratische.google.BaseException;
import com.googlecode.maratische.google.dao.CommandDao;
import com.googlecode.maratische.google.model.Command;
import com.googlecode.maratische.google.model.Commands;

public class CommandDaoImpl extends BaseDaoImpl<Command> implements CommandDao {

	public CommandDaoImpl(Connection conn) {
		super(conn);
	}

	public int sizeOfCommands() throws SQLException {
		String sql = "select count(*) as kol from "+getTableName()+" ";
		PreparedStatement statement = this.conn.prepareStatement(sql);
		ResultSet rs = statement.executeQuery();
		while (rs.next()) {
			return rs.getInt("kol");
		}
		return 0;
	}
	
	/**
	 * find by command
	 * @param command
	 * @return
	 * @throws SQLException
	 * @throws BaseException 
	 */
	private List<Command> findByCommand(Command command) throws SQLException, BaseException {
		ArrayList<Command> result = new ArrayList<Command>();
		String sql = "select * from "+getTableName()+" WHERE TYPE = ? AND STRING1 = ? AND STRING2 = ? AND INTEGER1 = ?";
		PreparedStatement statement = this.conn.prepareStatement(sql);
		statement.setString(1, command.getType());
		if (command.getString1() != null) {
			statement.setString(2, command.getString1());
		} else {
			statement.setNull(2, Types.VARCHAR);
		}
		if (command.getString2() != null) {
			statement.setString(3, command.getString2());
		} else {
			statement.setNull(3, Types.VARCHAR);
		}
		if (command.getInteger1() != null) {
			statement.setInt(4, command.getInteger1());
		} else {
			statement.setNull(4, Types.VARCHAR);
		}
		ResultSet rs = statement.executeQuery();
		while (rs.next()) {
			result.add(createByRow(rs));
		}
		return result;
	}
	
	/**
	 * we do not save dublicated command
	 * @throws BaseException 
	 */
	@Override
	public Command save(Command object) throws SQLException, BaseException {
		if (findByCommand(object).size()==0) {
			// TODO Auto-generated method stub
			return super.save(object);
		}
		return object;
	}
	
	@Override
	public Command createByRow(ResultSet rs) throws SQLException, BaseException {
		Command command = Command.createCommand(Commands.valueOf(rs.getString("TYPE")));
		if (command != null) {
			command.setId(rs.getInt("ID"));
			command.setString1(rs.getString("STRING1"));
			command.setString2(rs.getString("STRING2"));
			command.setInteger1(rs.getInt("INTEGER1"));
		}
		return command;
	}

	@Override
	protected String generateInsertSql() {
		return "insert into "+getTableName()+" (TYPE,PRIORITY, STRING1, STRING2, INTEGER1) values (?,?, ?,?, ?)";
	}

	@Override
	protected String generateUpdateSql() {
		return "update "+getTableName()+" set TYPE = ?,PRIORITY = ?, STRING1 = ?, STRING2 = ?, INTEGER1 = ? "+
		" where ID = ? ";
	}

	@Override
	protected String getTableName() {
		return "COMMAND";
	}

	@Override
	protected PreparedStatement putInsertPrepareStatement(PreparedStatement pStat, Command status) throws SQLException {
		pStat.setString(1, status.getType());
		pStat.setInt(2, status.getPriority());
		pStat.setString(3, status.getString1());
		pStat.setString(4, status.getString2());
		pStat.setInt(5, status.getInteger1());
		return pStat;
	}
	
	@Override
	protected PreparedStatement putUpdatePrepareStatement(PreparedStatement pStat, Command status) throws SQLException {
		pStat = putInsertPrepareStatement(pStat, status);
		pStat.setInt(6, status.getId());
		return pStat;
	}

	@Override
	public List<Command> listByPriority() throws SQLException, BaseException {
		return list("PRIORITY, ID");
	}

}
